#-*- codeing = utf-8 -*-
#@Time : 2020/11/25 16:43
#@Author : 阳某
#@File : 16.多进程.py
#@Software : PyCharm


# Python 官方解释器 的每个线程要获得执行权限，必须获取一个叫 GIL （全局解释器锁） 的东西。
#
# 这就导致了 Python 的多个线程 其实 并不能同时使用 多个CPU核心。
#
# 所以如果是计算密集型的任务，不能采用多线程的方式。
from threading import Thread

def f():
    while True:
        b = 53*53

if __name__ == '__main__':
    plist = []
    # 启动10个线程
    for i in range(10):
        p = Thread(target=f)
        p.start()
        plist.append(p)

    for p in plist:
        p.join()
# 运行后，打开任务管理器，可以发现 即使是启动了10个线程，依然只能占用一个CPU核心的运算能力。
# 如下图所示，我的电脑有4个核心，这个Python进程占用了1个核心的运行能力，所以下图显示25，表示 25% ，也就是 1/4的CPU占用率



# 如果需要利用电脑多个CPU核心的运算能力，可以使用Python的多进程库，如下
from multiprocessing import Process

def f():
    while True:
        b = 53*53

if __name__ == '__main__':
    plist = []
    for i in range(2):
        p = Process(target=f)
        p.start()
        plist.append(p)

    for p in plist:
        p.join()



# 还有一个问题，主进程如何获取 子进程的 运算结果呢？
# 可以使用多进程库 里面的 Manage 对象，如下
from multiprocessing import Process,Manager
from time import sleep

def f(taskno,return_dict):
    sleep(2)
    # 存放计算结果到共享对象中
    return_dict[taskno] = taskno

if __name__ == '__main__':
    manager = Manager()
    # 创建 类似字典的 跨进程 共享对象
    return_dict = manager.dict()
    plist = []
    for i in range(10):
        p = Process(target=f, args=(i,return_dict))
        p.start()
        plist.append(p)

    for p in plist:
        p.join()

    print('get result...')
    # 从共享对象中取出其他进程的计算结果
    for k,v in return_dict.items():
        print (k,v)